package com.arrcen.medicen.core.match.service;

import com.alibaba.fastjson.JSON;
import com.arrcen.medicen.core.match.mapper.MapperHelper;
import com.arrcen.medicen.core.match.mapper.SequenceMapper;
import com.arrcen.medicen.core.match.model.entity.SequenceEntity;
import com.arrcen.medicen.core.match.model.entity.SyncTableEntity;
import com.arrcen.medicen.core.match.utlity.EntityHelper;
import com.arrcen.medicen.core.match.utlity.lambda2sql.Lambda2Sql;
import com.arrcen.medicen.core.match.utlity.lambda2sql.SqlPredicate;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BaseService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {

    @Autowired
    MapperHelper mapperHelper;

    EntityHelper<T> entityHelper;


    @Autowired
    SequenceMapper seqMapper;

    private <TT> String LambdaToSql(EntityHelper<TT> entityHelper, SqlPredicate<TT> whereLambda) {
        String whereStr = Lambda2Sql.toSql(whereLambda);
        Pattern p = Pattern.compile("\\{(.*?)\\}");//正则表达式，取{和}之间的字符串，不包括=和|
        Matcher m = p.matcher(whereStr);
        HashMap<String, String> allItem = entityHelper.getEntityMapNameColumn();
        while (m.find()) {
            whereStr = whereStr.replaceAll("(\\{*)" + m.group(1) + "(\\}*)", allItem.get(m.group(1)));
        }
        return whereStr;
    }


    public List<T> list(Class<T> classType , String whereStr, int pageIndex, int pageSize, List<String> allItems) {
        if(entityHelper==null)
            entityHelper=new EntityHelper<T>(classType);
        List<HashMap<String, Object>> map = mapperHelper.getAll(entityHelper, whereStr, pageIndex, pageSize, allItems);
        String str = JSON.toJSONString(map);
        List<T> ent = JSON.parseArray(str, classType);
        return ent;
    }

    public List<T> list(Class<T> classType , SqlPredicate<T> whereLambda, int pageIndex, int pageSize, List<String> allItems) {
        if(entityHelper==null) entityHelper=new EntityHelper<T>(classType);
        String whereStr = LambdaToSql(entityHelper, whereLambda);
        return list(classType, whereStr, pageIndex, pageSize, allItems);
    }

    public T getOne(Class<T> classType , SqlPredicate<T> whereLambda) {
        if(entityHelper==null) entityHelper=new EntityHelper<T>(classType);
        String whereStr = LambdaToSql(entityHelper, whereLambda);
        List<T> list = list(classType, whereStr, 1, 1, null);
        if(list.size()>0){
            return list.get(0);
        }
        return null;
    }

    public int delete(Class<T> classType , SqlPredicate<T> whereLambda) {
        if(entityHelper==null) entityHelper=new EntityHelper<T>(classType);
        String whereStr = LambdaToSql(entityHelper, whereLambda);
        int reInt = mapperHelper.delete(entityHelper, whereStr);
        return reInt;
    }


    public int getIncreasingId(Class<T> classType) {
        entityHelper=new EntityHelper<T>(classType);
        String tableName=entityHelper.tableName;
        SequenceEntity ent= seqMapper.selectById(tableName);
        if(ent==null){
            ent=new SequenceEntity();
            ent.setCurrentVal(1);
            ent.setSeqName(tableName);
            ent.setIncrementVal(1);
            seqMapper.insert(ent);
            return ent.getCurrentVal();
        }
        else {
            ent.currentVal+=ent.getIncrementVal();
            SequenceEntity saveEnt=new SequenceEntity();
            saveEnt.setSeqName(ent.getSeqName());
            saveEnt.setCurrentVal(ent.currentVal);
            seqMapper.updateById(ent);
        }
        return ent.currentVal;
    }

    /**
     *
     * @param tableName
     * @param num
     * @return
     */
    public List<Integer> getIncreasingIdList(String tableName, int num) {
        SequenceEntity ent= seqMapper.selectById(tableName);
        if(num<0)num=1;
        List<Integer> reList=new ArrayList<>();
        int i = 1;
        if(ent==null){
            ent=new SequenceEntity();
            for (; i <= num; i++) {
                reList.add(i);
            }
            ent.setCurrentVal(i);
            ent.setSeqName(tableName);
            ent.setIncrementVal(1);
            seqMapper.insert(ent);

            return reList;
        }
        else {
            i = 1;
            int v=0;
            for ( ;i <= num; i++) {
                v=ent.getCurrentVal()+i*ent.getIncrementVal();
                reList.add(v);
            }
            SequenceEntity saveEnt=new SequenceEntity();
            saveEnt.setSeqName(ent.getSeqName());
            saveEnt.setCurrentVal(v);
            seqMapper.updateById(saveEnt);
        }
        return reList;
    }
}

